'*******************************************************************************
' *  
' *  Product: GSALib
' *  Description: A C# API for accessing the Google Search Appliance.
' *
' *  (c) Copyright 2008 Michael Cizmar + Associates Ltd.  (MC+A)
' *  
'*******************************************************************************


Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Text
Imports GSALibVB.GSALib.Utils
Imports GSALibVB.GSALib.Constants

Namespace GSALib.GSA
    ''' <summary>
    ''' Class creates Query object that will be used for submitting http requests to GSA
    ''' <para>Author Albert Ghukasyan</para>
    ''' </summary>
    Public NotInheritable Class Query
#Region "Variables"

        Public Shared MAX_RESULTS As Integer = 1000
        Public Shared MAX_RESULTS_PER_QUERY As Integer = 100
        Private query As QueryBuilder
        Private queryTerm As QueryTerm

#End Region

#Region "Constructor"

        Public Sub New()
            query = New QueryBuilder("", Nothing)
            query.setOutput(Output.XML_NO_DTD.getValue())
        End Sub

#End Region

#Region "Get/Set Properties"

        Public Sub setSiteCollections(ByVal siteCollections As String())
            query.setSites(siteCollections)
        End Sub

        Public Sub setFrontend(ByVal frontend As String)
            query.setClient(frontend)
        End Sub

        Public Sub setOutputFormat(ByVal [of] As Output)
            query.setOutput([of].getValue())
        End Sub

        Public Sub setMaxResults(ByVal maxResults As Integer)
            query.setNum(Math.Min(maxResults, MAX_RESULTS))
        End Sub

        Public Sub setNumKeyMatches(ByVal keyMatches As Byte)
            query.setNumgm(keyMatches)
        End Sub

        Public Sub setSearchScope(ByVal searchRgn As SearchRegion)
            query.setAs_occt(searchRgn.getValue())
        End Sub

        Public Sub setFilter(ByVal filtering As Filtering)
            query.setFilter(filtering.getValue())
        End Sub

        Public Sub setQueryTerm(ByVal queryTerm As QueryTerm)
            Me.queryTerm = queryTerm
            query.setQ(queryTerm.getValue())
        End Sub

        Public Sub setOrQueryTerms(ByVal orTerms As String())
            query.setAs_oq(orTerms)
        End Sub

        Public Sub setAndQueryTerms(ByVal andTerms As String())
            query.setAs_q(andTerms)
        End Sub

        Public Sub setExactPhraseQueryTerm(ByVal phrase As String)
            query.setAs_epq(phrase)
        End Sub

        Public Sub setInputEncoding(ByVal inputEncoding As String)
            query.setIe(inputEncoding)
        End Sub

        Public Sub setOutputEncoding(ByVal outputEncoding As String)
            query.setOe(outputEncoding)
        End Sub

        Public Sub setLanguage(ByVal language As String)
            query.setLr(language)
        End Sub

        Public Sub setFetchMetaFields(ByVal fields As String())
            query.setGetfields(fields)
        End Sub

        Public Sub setRequiredMetaFields(ByVal requiredFields As Hashtable)
            query.setRequiredfields(requiredFields, True)
        End Sub

        Public Sub setRequiredMetaFields(ByVal requiredFields As Hashtable, ByVal orIfTrueAndIfFalse As Boolean)
            query.setRequiredfields(requiredFields, orIfTrueAndIfFalse)
        End Sub

        Public Sub setPartialMetaFields(ByVal partialFields As Hashtable)
            query.setPartialfields(partialFields, True)
        End Sub

        Public Sub setPartialMetaFields(ByVal partialFields As Hashtable, ByVal orIfTrueAndIfFalse As Boolean)
            query.setPartialfields(partialFields, orIfTrueAndIfFalse)
        End Sub

        Public Sub setSortByDate(ByVal asc As Boolean, ByVal mode As Char)
            query.setSort("date:" + (IIf(asc, "A:", "D:")) + mode + ":d1")
        End Sub

        Public Sub unsetSortByDate()
            query.setSort(Nothing)
        End Sub

        Public Sub setScrollAhead(ByVal n As Integer)
            query.setStart(n)
        End Sub

        Public Sub setAccess(ByVal access As Access)
            query.setAccess(access.getValue())
        End Sub

        Public Function getAccess() As Char
            Return query.getAccess()
        End Function

        Public Sub setProxycustom(ByVal proxycustom As String)
            query.setProxycustom(proxycustom)
        End Sub

        Public Sub setProxystylesheet(ByVal proxystylesheet As String)
            query.setProxystylesheet(proxystylesheet)
        End Sub

        Public Sub setProxyReload(ByVal force As Boolean)
            query.setProxyreload(force)
        End Sub

        Public Function getValue() As String
            Return query.getValue()
        End Function

        Public Function getQueryString() As String
            Return queryTerm.getValue()
        End Function

#End Region
    End Class

    ''' <summary>
    ''' Class creates QueryTerm object that will be used for submitting http requests to GSA
    ''' <para> Class Object should be used to specify additional options of Query</para>
    ''' Author Albert Ghukasyan
    ''' </summary>
    Public NotInheritable Class QueryTerm
#Region "Variables"

        Private inTitleTerms As ArrayList
        Private notInTitleTerms As ArrayList
        Private inUrlTerms As ArrayList
        Private notInUrlTerms As ArrayList
        Private includeFiletype As ArrayList
        Private excludeFiletype As ArrayList
        Private allInTitleTerms As ArrayList
        Private allInUrlTerms As ArrayList
        Private site As String
        Private includeSite As Boolean
        Private dateRange As String
        Private webDocLocation As String
        Private cacheDocLocation As String
        Private link As String
        Private queryString As String

        Private Const _IN_TITLE As String = "intitle:"
        Private Const _NOT_IN_TITLE As String = "-intitle:"
        Private Const _IN_URL As String = "inurl:"
        Private Const _NOT_IN_URL As String = "-inurl:"
        Private Const _INCLUDE_FILETYPE As String = "filetype:"
        Private Const _EXCLUDE_FILETYPE As String = "-filetype:"
        Private Const _INCLUDE_SITE As String = "site:"
        Private Const _EXCLUDE_SITE As String = "-site:"
        Private Const _DATERANGE As String = "daterange:"
        Private Const _ALL_IN_TITLE As String = "allintitle:"
        Private Const _ALL_IN_URL As String = "allinurl:"
        Private Const _INFO As String = "info:"
        Private Const _CACHE As String = "cache:"
        Private Const _LINK As String = "link:"
        Private Const _OR As String = " OR "
        Private Const _SP As String = " "

#End Region

#Region "Constructor"

        Public Sub New(ByVal queryString As String)
            Me.queryString = queryString
        End Sub

#End Region

#Region "Get/Set Properties"

        Public Sub setQueryString(ByVal queryString As String)
            Me.queryString = queryString
        End Sub

        Public Sub setInTitle(ByVal inTitleTerms As ArrayList)
            Me.inTitleTerms = inTitleTerms
        End Sub

        Public Sub setNotInTitle(ByVal notInTitleTerms As ArrayList)
            Me.notInTitleTerms = notInTitleTerms
        End Sub

        Public Function addInTitle(ByVal term As String, ByVal include As Boolean) As QueryTerm
            If include Then
                inTitleTerms.Add(term)
            Else
                notInTitleTerms.Add(term)
            End If
            Return Me
        End Function

        Public Sub setAllInTitle(ByVal allInTitleTerms As ArrayList)
            Me.allInTitleTerms = allInTitleTerms
        End Sub

        Public Sub setInUrl(ByVal inUrlTerms As ArrayList)
            Me.inUrlTerms = inUrlTerms
        End Sub

        Public Sub setNotInUrl(ByVal notInUrlTerms As ArrayList)
            Me.notInUrlTerms = notInUrlTerms
        End Sub

        Public Function addInUrl(ByVal term As String, ByVal include As Boolean) As QueryTerm
            If include Then
                inUrlTerms.Add(term)
            Else
                notInUrlTerms.Add(term)
            End If
            Return Me
        End Function

        Public Sub setAllInUrl(ByVal allInUrlTerms As ArrayList)
            Me.allInUrlTerms = allInUrlTerms
        End Sub

        Public Sub setIncludeFileType(ByVal filetype As ArrayList)
            Me.includeFiletype = filetype
        End Sub

        Public Sub setExcludeFileType(ByVal filetype As ArrayList)
            Me.excludeFiletype = filetype
        End Sub

        Public Function addFileType(ByVal term As String, ByVal include As Boolean) As QueryTerm
            If include Then
                If includeFiletype Is Nothing Then
                    includeFiletype = New ArrayList()
                End If
                includeFiletype.Add(term)
            Else
                If excludeFiletype Is Nothing Then
                    excludeFiletype = New ArrayList()
                End If
                excludeFiletype.Add(term)
            End If
            Return Me
        End Function

        Public Sub setSite(ByVal site As String, ByVal include As Boolean)
            Me.includeSite = include
            Me.site = site
        End Sub

        Public Sub setWebDocument(ByVal docLocation As String)
            Me.webDocLocation = docLocation
        End Sub

        Public Sub setCachedDocument(ByVal docLocation As String)
            Me.cacheDocLocation = docLocation
        End Sub

        Public Sub setWithLinksTo(ByVal link As String)
            Me.link = link
        End Sub

        Public Sub setDateRange(ByVal fromDate As DateTime, ByVal toDate As DateTime)
            Dim dateRange As New StringBuilder(fromDate.ToString("YYYY-MM-DD"))
            dateRange.Append("..")
            dateRange.Append(toDate.ToString("YYYY-MM-DD"))
            Me.dateRange = dateRange.ToString()
        End Sub

#End Region

#Region "getValue"

        Public Function getValue() As String
            Dim retval As String = Nothing
            Dim qbuf As New StringBuilder()
            If allInTitleTerms IsNot Nothing AndAlso allInTitleTerms.Count > 0 Then
                qbuf.Append(_ALL_IN_TITLE).Append(Util.SeparatedString(allInTitleTerms, Nothing, _SP)).Append(" "c)
            End If
            If allInUrlTerms IsNot Nothing AndAlso allInUrlTerms.Count > 0 Then
                qbuf.Append(_ALL_IN_URL).Append(Util.SeparatedString(allInUrlTerms, Nothing, _SP)).Append(" "c)
            End If

            If webDocLocation IsNot Nothing AndAlso webDocLocation.Length > 0 Then
                qbuf.Append(_INFO).Append(webDocLocation).Append(" "c)
            End If

            If cacheDocLocation IsNot Nothing AndAlso cacheDocLocation.Length > 0 Then
                qbuf.Append(_CACHE).Append(cacheDocLocation).Append(" "c)
            End If
            If link IsNot Nothing AndAlso link.Length > 0 Then
                qbuf.Append(_LINK).Append(link)
            End If

            If inTitleTerms IsNot Nothing AndAlso inTitleTerms.Count > 0 Then
                qbuf.Append(Util.SeparatedString(inTitleTerms, _IN_TITLE, _SP)).Append(" "c)
            End If
            If notInTitleTerms IsNot Nothing AndAlso notInTitleTerms.Count > 0 Then
                qbuf.Append(Util.SeparatedString(notInTitleTerms, _NOT_IN_TITLE, _SP)).Append(" "c)
            End If

            If inUrlTerms IsNot Nothing AndAlso inUrlTerms.Count > 0 Then
                qbuf.Append(Util.SeparatedString(inUrlTerms, _IN_URL, _SP)).Append(" "c)
            End If
            If notInUrlTerms IsNot Nothing AndAlso notInUrlTerms.Count > 0 Then
                qbuf.Append(Util.SeparatedString(notInUrlTerms, _NOT_IN_URL, _SP)).Append(" "c)
            End If

            If site IsNot Nothing AndAlso site.Length > 0 Then
                qbuf.Append(IIf(includeSite, _INCLUDE_SITE, _EXCLUDE_SITE)).Append(site).Append(" "c)
            End If

            If includeFiletype IsNot Nothing AndAlso includeFiletype.Count > 0 Then
                qbuf.Append(Util.SeparatedString(includeFiletype, _INCLUDE_FILETYPE, _OR)).Append(" "c)
            End If
            If excludeFiletype IsNot Nothing AndAlso excludeFiletype.Count > 0 Then
                qbuf.Append(Util.SeparatedString(excludeFiletype, _EXCLUDE_FILETYPE, _SP)).Append(" "c)
            End If
            If dateRange IsNot Nothing Then
                qbuf.Append(_DATERANGE).Append(dateRange).Append(" "c)
            End If

            If queryString IsNot Nothing Then
                qbuf.Append(queryString)
            End If

            retval = qbuf.ToString()
            Return retval
        End Function

#End Region
    End Class
End Namespace
